#ifndef CPP_POOL_H
#define CPP_POOL_H

#include <Global.h>
#include <cmath>
#include <limits>
#include <vector>

template <class T>
class Pool {
   public:
    Pool(int initialCapacity = 16, int max = std::numeric_limits<int>::max(), bool allocate = false) : mMax(max) {
        create(initialCapacity, allocate);
    };
    ~Pool() {
        cvte_log_info("start free pool:%d", (int)mFreeObjects.size());
        class std::vector<T*>::iterator it;
        for (it = mFreeObjects.begin(); it != mFreeObjects.end();) {
            T* obj = *it;
            //删除元素，返回值指向已删除元素的下一个位置
            it = mFreeObjects.erase(it);
            delete obj;
            obj = nullptr;
        }
        cvte_log_info("end free pool:%d", (int)mFreeObjects.size());
        mMax = 0;
    };

    T* obtain() {
        if (mFreeObjects.size() == 0) {
            cvte_log_info("obtain new object");
            return new T();
        } else {
            cvte_log_info("obtain object from pool");
            T* obj = mFreeObjects.back();
            mFreeObjects.pop_back();
            return obj;
        }
    };

    void free(T* const t) {
        if (t == nullptr) {
            return;
        }
        if (mFreeObjects.size() < mMax) {
            mFreeObjects.push_back(t);
        } else {
            delete t;
        }
    };

   private:
    void create(int initialCapacity, bool allocate) {
        mFreeObjects.reserve(initialCapacity);
        if (allocate) {
            for (int i = 0; i < initialCapacity; ++i) {
                mFreeObjects.push_back(new T());
            }
        }
    }
    std::vector<T*> mFreeObjects;
    int mMax = 16;
};

#endif /* CPP_POOL_H */